﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;

namespace hopchat
{
    public class hop_chat
    {
        private string loai; 
        private string tinhchat;
        private List<DonChat> thanhphan;    //cac thanh phan cua hop chat

        public string _loai // tu dong cap nhat loai cua thanh phan
        {
            get{
                return loai;
            }
            set {
                loai = value;
            }
        }

        public string _tinhchat //tu dong cap nhat tinh chat cua thanh phan
        {
            get {
                return tinhchat;
            }
            set {
                tinhchat = value;
            }
        }

        public List<DonChat> _thanhphan
        {
            get {
                return thanhphan;
            }
            set {
                _thanhphan = value;
            }
        }

        public hop_chat() {
            thanhphan = new List<DonChat>();
            thanhphan.Add(null);
            thanhphan.Add(null);
        }

        public hop_chat(hop_chat a)
        {
            thanhphan = new List<DonChat>();
            thanhphan.Add(null);
            thanhphan.Add(null);

            this.ganbang(a);
        }

        public hop_chat(string _loai = null, string _tinhchat = null, List<DonChat> _thanhphan = null)
        {
            //xac dinh loai cua hop chat
            loai = _loai;

            //xac dinh tinh chat cua hop chat
            tinhchat = _tinhchat;

            //luu cac don chat cua hop chat
            thanhphan = new List<DonChat>();
            if (_thanhphan != null)
                foreach (DonChat a in _thanhphan)
                    thanhphan.Add(a);
            else {
                thanhphan.Add(null);
                thanhphan.Add(null);
            }
        }

        public override string ToString()
        {
            string result = "[";

            if (!object.Equals( this._loai, null))
                result += "\"" + this.loai.Trim() +"\"";

            if (this.xdten() != "")
            {
                if (result != "[") result += ", ";
                result += "\"" + this.xdten() + "\"";
            }
            if (!object.Equals(this._tinhchat, null))
            {
                if (result != "[") result += ", ";
                result += "\"" + this.tinhchat.Trim() + "\"";
            }

            if (result != "[") result += ", ";
            if (this.xdcongthuc() != "")
            {
                
                result += "\"" + this.xdcongthuc() + "\"";
            }
            else
            {
                if (!object.Equals(thanhphan[0], null))
                    result += thanhphan[0].ToString();
                else
                    result += "[]";

                if (!object.Equals(thanhphan[1], null))
                    result +=  thanhphan[1].ToString();
                else
                    result += "[]";
            }
            result += "]";
            return result;
        }

        public hop_chat(XmlDocument data)
        {
            XmlNode child = data.GetElementsByTagName("loai")[0];

            if (child.InnerText != "")
                loai = child.InnerText;
            else loai = null;
            child = data.GetElementsByTagName("tinhchat")[0];
            if (child.InnerText != "")
                tinhchat = child.InnerText;
            else tinhchat = null;

            thanhphan = new List<DonChat>();

            child = data.GetElementsByTagName("thanhphan")[0];
            XmlDocument doc = new XmlDocument();
            XmlElement temp;

            if (child.InnerXml == "")
            {
                thanhphan.Add(null);
                thanhphan.Add(null);
            }
            else 
                for (int i = 0; i < 2; i++)
                {
                    doc = new XmlDocument();
                    temp = doc.CreateElement("DonChat");
                
                    if (child.ChildNodes[i].InnerXml != "")
                    {
                        temp.InnerXml = child.ChildNodes[i].InnerXml;
                        doc.AppendChild(temp);
                        thanhphan.Add(new DonChat(doc));
                    }
                    else thanhphan.Add(null);
                }
            
        }


        /*
         * If this hop_chat is in the list data, return false
         */
        public bool checklist(List<hop_chat> data)
        {
            
            foreach (hop_chat a in data)
                if (a == this)
                    return false;
            return true;
        }

        public XmlDocument ExportToXML()    //tao xmlDocument tu class
        {
            // Set up the XmlDocument 
            XmlDocument HopChat = new XmlDocument();
            
            // Create the new node 
            XmlElement root = HopChat.CreateElement("hopchat");
            XmlElement child = HopChat.CreateElement("loai");
            child.InnerText = _loai;
            root.AppendChild(child);

            child = HopChat.CreateElement("tinhchat");
            child.InnerText = _tinhchat;
            root.AppendChild(child);

            child = HopChat.CreateElement("thanhphan");
            
            for (int i = 0; i < thanhphan.Count; i++)
            {
                XmlElement childE = HopChat.CreateElement("DonChat");
                if (!object.Equals(thanhphan[i], null))
                    childE.InnerXml = thanhphan[i].ExportToXML().DocumentElement.InnerXml;
                else childE.InnerText = null;
                child.AppendChild(childE);
            }
            root.AppendChild(child);
            HopChat.AppendChild(root);

            return HopChat;
        }


        public void ExportToXML(string path)    //tao xmlDocument tu class
        {
            
            // Set up the XmlDocument 
            XmlDocument HopChat = new XmlDocument();

            // Create the new node 
            XmlElement root = HopChat.CreateElement("hopchat");
            XmlElement child = HopChat.CreateElement("loai");
            child.InnerText = _loai;
            root.AppendChild(child);

            child = HopChat.CreateElement("tinhchat");
            child.InnerText = _tinhchat;
            root.AppendChild(child);

            child = HopChat.CreateElement("thanhphan");

            for (int i = 0; i < thanhphan.Count; i++)
            {
                XmlElement childE = HopChat.CreateElement("DonChat");
                if (!object.Equals(thanhphan[i], null))
                    childE.InnerXml = thanhphan[i].ExportToXML().DocumentElement.InnerXml;
                else childE.InnerText = null;
                child.AppendChild(childE);
            }
            root.AppendChild(child);
            HopChat.AppendChild(root);

            HopChat.Save(path);

            
        }

        public string xdcongthuc()  // xac dinh cong thuc cho hop chat
        {
            if (object.Equals( thanhphan[0] ,null ) || object.Equals( thanhphan[1] , null) )
                return "";
            if (object.Equals( thanhphan[0].Cong_Thuc , null) || object.Equals( thanhphan[0].Hoa_Tri, 0) )
                return "";
            if (object.Equals( thanhphan[1].Cong_Thuc, null) || object.Equals( thanhphan[1].Hoa_Tri, 0))
                return "";

            int ht1, ht2, temp;
            ht1 = thanhphan[0].Hoa_Tri;
            ht2 = thanhphan[1].Hoa_Tri;

            //rut gon hoa tri
            if (ht1 == ht2)
                ht1 = ht2 = 1;
            else {
                if (ht1 > ht2)
                {
                    temp = ht1;
                    while (ht1 > ht2)
                    {
                        ht1 = ht1 - ht2;
                        temp = ht1;
                    }
                    ht1 = thanhphan[0].Hoa_Tri / temp;
                    ht2 = thanhphan[1].Hoa_Tri / temp;
                }
                else
                {
                    temp = ht2;
                    while (ht2 > ht1)
                    {
                        ht2 = ht2 - ht1;
                        temp = ht2;
                    }
                    ht1 = thanhphan[0].Hoa_Tri / temp;
                    ht2 = thanhphan[1].Hoa_Tri / temp;
                }
            }

            //xac dinh cong thuc
            string congthuc1 = "";
            string congthuc2 = "";
            List<int> count = new List<int>();
            count.Add(0); count.Add(0);
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < thanhphan[i].Cong_Thuc.Length; j++)
                    if ((thanhphan[i].Cong_Thuc[j] >= 65) && (thanhphan[i].Cong_Thuc[j] <= 90))
                        count[i]++;
            }

            if (ht2 != 1)
                if (count[0] == 1)
                    congthuc1 = thanhphan[0].Cong_Thuc + ht2;
                else congthuc1 = "(" + thanhphan[0].Cong_Thuc + ")" + ht2;
            else congthuc1 += thanhphan[0].Cong_Thuc;

            if (ht1 != 1)
                if (count[1] == 1)
                    congthuc2 = thanhphan[1].Cong_Thuc + ht1;
                else congthuc2 = "(" + thanhphan[1].Cong_Thuc + ")" + ht1;
            else congthuc2 += thanhphan[1].Cong_Thuc;

            return congthuc1 + congthuc2;
        }

        public string xdten()
        {
            string ten = "";
            if (object.Equals( thanhphan[0] , null ) || object.Equals( thanhphan[1] , null ) || object.Equals(thanhphan[0].Ten_goi, null ) || object.Equals( thanhphan[1].Ten_goi ,null))
                return "";
            ten = thanhphan[0].Ten_goi + " " + thanhphan[1].Ten_goi;
            return ten;
        }

        public string lowerhopchat(string data)
        {
            if (data != null)
                return data.Trim().ToLower();
            return null;
        }


        
        public static bool operator==(hop_chat hc1, hop_chat hc2)
        {
            if (object.Equals(null, hc2)) return true;
            if ((hc2._loai == null) && (hc2._tinhchat == null) && (object.Equals(hc2.thanhphan, null))) return true;
            if (object.Equals(null, hc1)) return false;
            if ((hc2._loai == null) || (hc1.lowerhopchat(hc1._loai) == hc2.lowerhopchat(hc2._loai)))
                if ((hc2._tinhchat == null) || (hc1.lowerhopchat(hc1._tinhchat) == hc2.lowerhopchat(hc2._tinhchat)))
                    if ((hc2.thanhphan == null) || ((hc1.thanhphan[0] == hc2.thanhphan[0]) && (hc1.thanhphan[1] == hc2.thanhphan[1])))
                        return true;
            return false;
        }

        public static bool operator!=(hop_chat hc1, hop_chat hc2)
        {
            return (!(hc1 == hc2));
        }

        public bool ganbang(hop_chat A)
        {
            bool check = false;
            if (this._loai == null && A._loai != null)
            {
                this._loai = A._loai;
                check = true;
            }

            if (this._tinhchat == null && A._tinhchat != null)
            {
                this._tinhchat = A._tinhchat;
                check = true;
            }

            if( (!object.Equals(A.thanhphan[0],null)))
            {
                if (object.Equals(this.thanhphan[0], null))
                    this.thanhphan[0] = new DonChat();
                if (this.thanhphan[0].GanBang(A.thanhphan[0]))
                    check = true;
            }

            if ((!object.Equals(A.thanhphan[1], null)))
            {
                if (object.Equals(this.thanhphan[1], null))
                    this.thanhphan[1] = new DonChat();
                if (this.thanhphan[1].GanBang(A.thanhphan[1]))
                    check = true;
            }

            
            return check;
        }
    }

    public class DonChat
    {
        private int ht;
        private string l;
        private string ct;
        private string tengoi;

        public int Hoa_Tri
        {
            get { return ht; }
            set { ht = value; }
        }
        public string Ten_goi
        {
            get { return tengoi; }
            set { tengoi = value; }
        }
        public string Loai
        {
            get { return l; }
            set { l = value; }
        }
        public string Cong_Thuc
        {
            get { return ct; }
            set { ct = value; }
        }
        public DonChat()
        {
        }

        public override string ToString()
        {
            string result = "[";

            if (!object.Equals( this.Loai, null))
                result += "\"" + this.Loai.Trim() +"\"";

            if (!object.Equals(this.Cong_Thuc, null))
            {
                if (result != "[") result += ", ";
                result += "\"" + this.Cong_Thuc.Trim() + "\"";
            }
            result += "]";
            return result;
        }

        public DonChat(string _tengoi = null, string _hoatri = null, string _loai = null, string _congthuc = null)
        {
            //ht = _hoatri == null ? 0 : int.Parse(_hoatri);
            if (_hoatri == null || _hoatri == "")
                ht = 0;
            else ht = int.Parse(_hoatri);

            l = _loai == "" ? null : _loai;
            ct = _congthuc == "" ? null : _congthuc;
            tengoi = _tengoi == "" ? null : _tengoi;
        }

        public DonChat(XmlDocument xDoc)
        {
            XmlNodeList lstNode = xDoc.GetElementsByTagName("DonChat");

            tengoi = lstNode[0].ChildNodes[0].InnerText == "" ? null : lstNode[0].ChildNodes[0].InnerText;
            ht = lstNode[0].ChildNodes[1].InnerText == "" ? 0 : int.Parse(lstNode[0].ChildNodes[1].InnerText);
            l = lstNode[0].ChildNodes[2].InnerText == "" ? null : lstNode[0].ChildNodes[2].InnerText;
            ct = lstNode[0].ChildNodes[3].InnerText == "" ? null : lstNode[0].ChildNodes[3].InnerText;

            /* // Nhu nhau, cai thu 3 danh truong hop FirstCHild co them node con
            MessageBox.Show(lstNode[0].FirstChild.InnerText);
            MessageBox.Show(lstNode[0].ChildNodes[0].InnerText);
            MessageBox.Show(lstNode[0].FirstChild.ChildNodes[0].InnerText);
            */
        }
        public XmlDocument ExportToXML()
        {
            //string strFilename = path;

            // Set up the XmlDocument 
            XmlDocument DonChat = new XmlDocument();

            // Create the new element 
            XmlElement eleNew = DonChat.CreateElement("DonChat");
            DonChat.AppendChild(eleNew);

            eleNew = DonChat.CreateElement("Ten");
            XmlText txtVideo = DonChat.CreateTextNode(this.Ten_goi);
            DonChat.LastChild.AppendChild(eleNew);
            DonChat.LastChild.LastChild.AppendChild(txtVideo);

            eleNew = DonChat.CreateElement("Hoa_tri");
            txtVideo = DonChat.CreateTextNode(this.Hoa_Tri.ToString());
            DonChat.LastChild.AppendChild(eleNew);
            DonChat.LastChild.LastChild.AppendChild(txtVideo);

            eleNew = DonChat.CreateElement("Loai");
            txtVideo = DonChat.CreateTextNode(this.Loai);
            DonChat.LastChild.AppendChild(eleNew);
            DonChat.LastChild.LastChild.AppendChild(txtVideo);

            eleNew = DonChat.CreateElement("Cong_thuc");
            txtVideo = DonChat.CreateTextNode(this.Cong_Thuc);
            DonChat.LastChild.AppendChild(eleNew);
            DonChat.LastChild.LastChild.AppendChild(txtVideo);

            //Save the xml file
            return DonChat;
        }

        public string convertIntToString(int i)
        {
            string a;
            switch (i)
            {
                case 1: a = "I"; break;
                case 2: a = "II"; break;
                case 3: a = "III"; break;
                case 4: a = "IV"; break;
                case 5: a = "V"; break;
                case 6: a = "VI"; break;
                default: a = "I"; break;
            }
            return a;
        }

        private string toLower(string data)
        {
            if (data != null)
                return data.ToLower();
            else return null;
        }
        public bool GanBang (DonChat A)
        {
            bool check = false;
            if (this.Hoa_Tri == 0 && A.Hoa_Tri != 0)
            {
                this.Hoa_Tri = A.Hoa_Tri;
                check = true; 
            }

            if (this.Ten_goi == null && A.Ten_goi != null)
            {
                this.Ten_goi = A.Ten_goi;
                check = true;
            }

            if (this.Cong_Thuc == null && A.Cong_Thuc != null)
            {
                this.Cong_Thuc = A.Cong_Thuc;
                check = true;
            }

            if (this.Loai == null && A.Loai != null)
            {
                this.Loai = A.Loai;
                check = true;
            }
            return check;
        }

        public static bool operator ==(DonChat A, DonChat B)
        {
            if (object.Equals(null, B))
                return true;
            if (B.Hoa_Tri == 0 && B.Loai == null && B.Ten_goi == null && B.Cong_Thuc == null)
                return true;
            
            if (object.Equals(null, A))
                return false;
            bool kqua = false;
                       /*
            if ((A.Hoa_Tri != 0 && B.Hoa_Tri == 0) || (A.Hoa_Tri == 0 && B.Hoa_Tri != 0))
                return kqua;
            if ((A.Loai != null && B.Loai == null) || (A.Loai == null && B.Loai != null))
                return kqua;
            if ((A.Ten_goi != null && B.Ten_goi == null) || (A.Ten_goi == null && B.Ten_goi != null))
                return kqua;
            if ((A.Cong_Thuc != null && B.Cong_Thuc == null) || (A.Cong_Thuc == null && B.Cong_Thuc != null))
                return kqua;
            */

            if (B.Cong_Thuc != null)
                if (A.toLower(A.Cong_Thuc) != B.toLower(B.Cong_Thuc))
                    return false;
                else
                    kqua = true;

            if (B.Hoa_Tri != 0)
                if (A.Hoa_Tri != B.Hoa_Tri)
                    return false;
                else
                    kqua = true;

            if (B.Loai != null)
                if (A.toLower(A.Loai) != B.toLower(B.Loai))
                    return false;
                else
                    kqua = true;

            //if (B.Ten_goi != null)
            //    if (A.toLower(A.Ten_goi) != B.toLower(B.Ten_goi))
            //        return false;
            //    else
            //        kqua = true;



            return kqua;
        }

        public static bool operator !=(DonChat A, DonChat B)
        {
            return !(A == B);
        }

    }
}
